package com.bestcem.xm.txtanls.config;

import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.zy.dp.proto.strontium.v1.SentimentEndpointGrpc;
import io.grpc.CallCredentials;
import io.grpc.Metadata;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import net.devh.boot.grpc.client.security.CallCredentialsHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Configuration
@Slf4j
public class BPClientConfig {

    @Value("${app.txtanls.dp.mock:true}")
    private boolean mockFlag;

    @Value("${app.txtanls.dp.auth.mock-api-key:mock}")
    private String mockApiKey;

    @Value("${app.txtanls.dp.auth.api-key:R0dPUbBAJq7u}")
    private String apiKey;

    @Value("${grpcService.dp.address:111111111}")
    private String addr;

    @Value("${app.txtanls.dp.auth.api-secret:2Q8GeLvAoFZj}")
    private String apiSecret;

    private static HMac hMac;

    @GrpcClient(GrpcClientNames.DP)
    private SentimentEndpointGrpc.SentimentEndpointBlockingStub sentimentEndpointBlockingStub;

    public static final String API_KEY = "api-key";

    public static final String API_TIMESTAMP = "api-timestamp";

    public static final String API_SIGNATURE = "api-signature";

    @Bean("txtanlsBPSentimentClient")
    public SentimentEndpointGrpc.SentimentEndpointBlockingStub authBPClient() {
        if (mockFlag) {
            return this.sentimentEndpointBlockingStub.withCallCredentials(mockGrpcCallCredentials());
        } else {
            String timestamp = String.valueOf(System.currentTimeMillis());
            return this.sentimentEndpointBlockingStub.withCallCredentials(grpcCallCredentials(timestamp));
        }
    }

    /**
     * mock请求情感预测接口
     *
     * @return
     */
    private CallCredentials mockGrpcCallCredentials() {
        final Metadata extraHeaders = new Metadata();
        extraHeaders.put(Metadata.Key.of(API_KEY, Metadata.ASCII_STRING_MARSHALLER), mockApiKey);
        return CallCredentialsHelper.authorizationHeaders(extraHeaders);
    }

    /**
     * 真实请求情感预测接口加签
     *
     * @param timestamp
     * @return
     */
    private CallCredentials grpcCallCredentials(String timestamp) {
        if (Objects.isNull(hMac)) {
            hMac = new HMac(HmacAlgorithm.HmacSHA256, apiSecret.getBytes(StandardCharsets.UTF_8));
        }
        String signature = hMac.digestHex(timestamp);
        final Metadata extraHeaders = new Metadata();
        log.info("[Txtanls BPClientConfig] addr:{}; api-key: {};api-timestamp: {};api-signature: {};", addr, apiKey, timestamp, signature);
        extraHeaders.put(Metadata.Key.of(API_KEY, Metadata.ASCII_STRING_MARSHALLER), apiKey);
        extraHeaders.put(Metadata.Key.of(API_TIMESTAMP, Metadata.ASCII_STRING_MARSHALLER), timestamp);
        extraHeaders.put(Metadata.Key.of(API_SIGNATURE, Metadata.ASCII_STRING_MARSHALLER), signature);
        return CallCredentialsHelper.authorizationHeaders(extraHeaders);
    }
}
